package view.overlay;

import inventory.EquipLocation;
import item.TakeableItem;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

import view.drawing.DrawState;
import view.drawing.StaticDrawState;
import entity.Entity;

public class ShopkeepingOverlay extends PassiveOverlay {

private Entity mEntity;
	
	private int mPaddingTop;
	private int mPaddingBottom;
	private int mPaddingLeft;
	private int mPaddingRight;
	
	private Rectangle mBounds;
	
	
	// Buttons for the inventory
	private CopyOnWriteArrayList<Button> mTheirButtons;
	private CopyOnWriteArrayList<Button> mMyButtons;
	
	private List<InventoryActionListener> mListeners;
	
	private boolean mIsFullVisible;
	
	
	private Button mThierInvNextPageButton;
	private Button mTheirInvPrevPageButton;
	
	private Button mMyInvNextPageButton;
	private Button mMyInvPrevPageButton;
	
	private Image mBackgroundImage;
	
	private Rectangle mTheirRect;
	private Rectangle mMyRect;
	
	private Map<TakeableItem, MouseListener> mTheirItems;
	private Map<TakeableItem, MouseListener> mMyItems;
	
	public ShopkeepingOverlay() {
		
		mBounds = new Rectangle(0, 0, this.getWidth(), this.getHeight());
		

		mTheirButtons = new CopyOnWriteArrayList<Button>();
		mMyButtons = new CopyOnWriteArrayList<Button>();
		
		
		// Map for takeableitems
		mTheirItems = new HashMap<TakeableItem, MouseListener>();
		mMyItems = new HashMap<TakeableItem, MouseListener>();
		
		// Create a list of inventory listeners
		mListeners = new ArrayList<InventoryActionListener>();
		
		// set default padding
		mPaddingLeft = 100;
		mPaddingRight = 100;
		mPaddingTop = 100;
		mPaddingBottom = 100;
		
		// Default to not all visible
		mIsFullVisible = false;
		
		mThierInvNextPageButton = new Button("Next");
		mTheirInvPrevPageButton = new Button("Prev");
		
		mMyInvNextPageButton = new Button("Next");
		mMyInvPrevPageButton = new Button("Prev");
		
		
	}

	@Override
	protected void paint(Graphics g) {
		
		
		// Only draw the full inventory if it is visible
		if (mIsFullVisible) {
			
			// If we have a background image, draw it, scaled to fit, the bounding rect
			if (mBackgroundImage != null) {
				g.drawImage(mBackgroundImage, mBounds.x, mBounds.y,
							mBounds.width, mBounds.height, null);
			}
			else {
				// Fill it with a background color
				g.setColor(new Color(179, 136, 69, 100));
				g.fillRect(mBounds.x, mBounds.y,
							mBounds.width, mBounds.height);
			}

			// ===========================================================================
			
			// Draw the borders
			g.setColor(new Color(106, 69, 10));
			
			// Draw My Rectangle
			g.draw3DRect(mMyRect.x,
					mMyRect.y,
					mMyRect.width,
					mMyRect.height,
					true);
			
			// Draw their Inventory Rectangle
			g.draw3DRect(mTheirRect.x,
					mTheirRect.y,
					mTheirRect.width,
					mTheirRect.height,
					true);
			
			// ===========================================================================
			
			// Draw the text
			String invString = "Their Inventory";
			String eqpString = "Your Inventory";
			
			// Set the color to white for text
			g.setColor(Color.WHITE);
			
			// Draw the text for the inventory
			Rectangle2D size = g.getFontMetrics().getStringBounds(invString, g);
			g.drawString(invString,
						(int)(mTheirRect.x + mTheirRect.getWidth() / 2 - size.getWidth() / 2),
						(int)(mTheirRect.y + size.getHeight() / 2) + 10);
							
			// Draw the text for the equipment
			size = g.getFontMetrics().getStringBounds(eqpString, g);
			g.drawString(eqpString,
					(int)(mMyRect.x + mMyRect.getWidth() / 2 - size.getWidth() / 2),
					(int)(mMyRect.y + size.getHeight() / 2) + 10);
			
			
			// ===========================================================================
			
			
			

			// Draw all the inventory items
			for (Button b : mTheirButtons) {
				b.draw(g);
			}
			
			// Draw all the inventory items
			for (Button b : mMyButtons) {
				b.draw(g);
			}
			
			// Draw the page buttons
			mThierInvNextPageButton.draw(g);
			mTheirInvPrevPageButton.draw(g);
			
			// Draw the page buttons
			mMyInvNextPageButton.draw(g);
			mMyInvPrevPageButton.draw(g);
		}
	}

	
	public void setInventoryItems(Map<TakeableItem, MouseListener> myItems, Map<TakeableItem, MouseListener> theirItems) {
		mTheirItems = theirItems;
		mMyItems = myItems;
		
		mTheirButtons.clear();
		mMyButtons.clear();
		
		calculateBounds();
		this.invalidate();
	}
	
	@Override
	public void onMouseClicked(MouseEvent e) {
		Point p = e.getPoint();
		
		
		if (mIsFullVisible) {
			// Loop through the bounding buttons for the inventory items
			for (Button b : mTheirButtons) {
				if (b.contains(p)) {
					b.activate(e);
				}
			}
			
			for (Button b : mMyButtons) {
				if (b.contains(p)) {
					b.activate(e);
				}
			}
			
		}
	}

	
	/**
	 * Helper method to avoid calculations unless they are really
	 * needed as there are a lot of them. Do not belong in paint()
	 */
	private void calculateBounds() {
		mBounds = new Rectangle(mPaddingLeft,
										mPaddingTop,
										this.getWidth() - mPaddingRight - mPaddingLeft,
										this.getHeight() - mPaddingBottom - mPaddingTop);
		
		// Divide the bounding rectangle into two pieces, one for equipment and one for inventory
		mMyRect = new Rectangle(mBounds.x, mBounds.y,
											mBounds.width / 2, mBounds.height);
		mTheirRect = new Rectangle(mBounds.x + (mBounds.width / 2), mBounds.y,
											mBounds.width / 2, mBounds.height);
		
		
		
		int buttonWidth = 75;
		int buttonHeight = 50;
		// Next and Prev button
		mThierInvNextPageButton.setBounds(mTheirRect.x + mTheirRect.width - buttonWidth - 5,
								mTheirRect.y + mTheirRect.height - buttonHeight - 5,
								buttonWidth,
								buttonHeight);
		
		mTheirInvPrevPageButton.setBounds(mTheirRect.x + 5,
								mTheirRect.y + mTheirRect.height - buttonHeight - 5,
								buttonWidth,
								buttonHeight);
		
		mMyInvNextPageButton.setBounds(mMyRect.x + mMyRect.width - buttonWidth - 5,
								mMyRect.y + mMyRect.height - buttonHeight - 5,
								buttonWidth,
								buttonHeight);

		mMyInvPrevPageButton.setBounds(mMyRect.x + 5,
								mMyRect.y + mMyRect.height - buttonHeight - 5,
								buttonWidth,
								buttonHeight);
		
		
		
		
		
		// === Inventory Items ===

		buttonWidth = mTheirRect.width - 10;
		buttonHeight = 35;
		
		int buttonVPadding = 10;
		int buttonHPadding = 10;
		

		int xOffset = mTheirRect.width / 2 - buttonWidth / 2;
		int yOffset = buttonVPadding*4;
		
		// Calculate the location for the item
		mTheirButtons.clear();

		for (TakeableItem ti : mTheirItems.keySet()) {
			
			if (ti == null) continue;
			

			
			Button button = new Button(ti.getName());
			button.setBounds(mTheirRect.x + xOffset,
							mTheirRect.y + yOffset,
							buttonWidth,
							buttonHeight);
			
			button.setListener(mTheirItems.get(ti));
			
			mTheirButtons.add(button);
			
			yOffset += buttonVPadding + buttonHeight;
			
			
		}
		
		xOffset = mMyRect.width / 2 - buttonWidth / 2;
		yOffset = buttonVPadding*4;
		
		// Calculate the location for the item
		mMyButtons.clear();

		for (TakeableItem ti : mMyItems.keySet()) {
			
			if (ti == null) continue;
			

			
			Button button = new Button(ti.getName());
			button.setBounds(mMyRect.x + xOffset,
							mMyRect.y + yOffset,
							buttonWidth,
							buttonHeight);
			
			button.setListener(mMyItems.get(ti));
			
			mMyButtons.add(button);
			
			yOffset += buttonVPadding + buttonHeight;
			
			
		}
		
		
	}

	@Override
	public Dimension getPreferredSize() {
		return (new Dimension(0, 0));
	}

	@Override
	public void resize(int width, int height) {
		super.resize(width, height);
		
		calculateBounds();
		updateInventory();
		
		// Invalidate as we have new bounds
		this.invalidate();
	}
	
	private void updateInventory() {
		if (mEntity == null) return;
		
		if (mTheirRect == null || mMyRect == null) {
			calculateBounds();
		}
		
	}

	
	public void showInventory() {
		mIsFullVisible = true;
		this.invalidate();
	}
	
	public void hideInventory() {
		mIsFullVisible = false;
		this.invalidate();
	}
	
	/**
	 * Toggles the visibility of the inventory
	 */
	public boolean toggleInventory() {
		if (mIsFullVisible) {
			hideInventory();
			
		}
		else {
			showInventory();
		}
		
		return (mIsFullVisible);
	}
	
	public void register(InventoryActionListener listener) {
		this.mListeners.add(listener);
	}
	
	public void unregister(InventoryActionListener listener) {
		this.mListeners.add(listener);
	}
	
	public interface InventoryActionListener {
		public void nextPage();
		public void prevPage();
	}
	
	public void setBackgroundImage(Image bg) {
		mBackgroundImage = bg;
	}
	
	public Image getBackgroundImage() {
		return (mBackgroundImage);
	}

	
	
	

}
